'use strict';

const fetch = require("fetch");
const later = require('later');
var EventEmitter = require('eventemitter3');

var EE = new EventEmitter();

const agents = require('../request/user_agent');
const flash = require('../request/flash_version');

const CapitalModel = require('../model/capital');

let url = "http://s1.dfcfw.com/allXML/index.xml?rt=" + Math.floor(new Date().getTime() / 30000);

// 模拟浏览器
let opt = {
    method: "GET",
    headers: {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, sdch",
        "Accept-Language": "zh-CN,zh;q=0.8",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Host": "s1.dfcfw.com",
        "Pragma": "no-cache",
        "Referer": "http://data.eastmoney.com/zjlx/dpzjlx.html",
        "User-Agent": agents[Math.floor(Math.random() * agents.length)],
        "X-Requested-With": flash[Math.floor(Math.random() * flash.length)]
    }
};

function parseData(res) {
    let data = {};
    data.items = [];
    res.split(/\r\n/).forEach(function (str, k) {
        if (/\d\d\d\d-\d\d-\d\d/.test(str)) {
            data.timeStamp = str;
        }
        if (/\d{1,3}:\d\d;/.test(str)) {
            data.items.push(str.split(';'));
        }
    });

    return data;
}

const realtimeCapitalFlow = function realtimeCapitalFlow() {
    return new Promise(function (resolve, reject) {
        fetch.fetchUrl(url, opt, function (error, meta, body) {
            if (error) {
                reject(`problem with request: ${error}`);
            } else {
                resolve({
                    meta: meta,
                    data: parseData(body.toString())
                });
            }
        });
    });
};

/**
 * 在此特定场景下的获取差异函数，根据 item.clockTime 来判定重复
 * @param oldList
 * @param newList
 * @returns {*}
 */
function getDiffList(oldList, newList) {
    return newList.filter(function (item, key) {
        return !oldList.some(function (v, k) {
            return v.clockTime === item.clockTime;
        });
    });
}

const capitalModel = new CapitalModel();

let lastUpdateTime = new Date();

function update() {
    // console.log('执行一次');
    realtimeCapitalFlow().then(function (res) {
        EE.emit('updatecapitaldata', res.data);
        capitalModel.then(function (capital) {
            // capital.find()
            //     .then(function(results) {
            //         console.log(results.length);
            //         let diffList = getDiffList(results, res.data.items);
            //     });
            res.data.items.forEach((item, key) => {
                (function (i) {
                    capital.create({
                        timeStamp: new Date(`${res.data.timeStamp.substring(0, 10)} ${i[0]}:00`),
                        clockTime: i[0],
                        super: Number(i[1]),
                        huge: Number(i[2]),
                        big: Number(i[3]),
                        medium: Number(i[4]),
                        small: Number(i[5])
                    })
                    // .then(function(capital){
                    //     return model.Stock.find().populate('capital');
                    // })
                    .catch(function (err) {
                        // If any errors occur execution jumps to the catch block.
                        console.error(err);
                    });
                })(item);
            });
        });
    });
}

//console.log("Now:"+new Date());


function range(a, b) {
    var min = Math.min(a, b);
    var max = Math.max(a, b);
    var re = [];
    for (var i = min; i < max + 1; i++) {
        re.push(i);
    }
    return re;
}

var sched = {
    schedules: [{ h: [9], m: range(30, 59) }, { h: [11], m: range(0, 30) }, { h: [10, 13, 14], m: range(0, 59) }, { h: [15], m: [0] }]
};

// 映射北京时间改成UTC时间
sched.schedules = sched.schedules.map(function (value) {
    return {
        h: value.h.map(function (v) {
            return Math.abs((v - 8) % 24);
        }),
        m: value.m
    };
});

// later.date.localTime();

later.date.UTC();

var t = later.setInterval(function () {
    update();
}, sched);

//setTimeout(function(){
//    t.clear();
//    console.log("Clear");
//},15*1000);

realtimeCapitalFlow.handleIO = function (socket) {
    socket.on('capital', function (data) {
        // data
    });

    update();

    EE.on('updatecapitaldata', function (capdata) {
        socket.emit('capital', capdata);
    });

    socket.on('disconnect', function () {});
};

// setInterval(function(){
//
//     update();
// }, 3000);

module.exports = realtimeCapitalFlow;

//var cookies = new fetch.CookieJar();
//
//// add one cookie for testing
//cookies.setCookie('alfa=beta; path=/;');

//const option = {
//    maxRedirects: void 0, // how many redirects allowed, defaults to 10
//    disableRedirects: void 0, // set to true if redirects are not allowed, defaults to false
//    headers: void 0, // optional header fields, in the form of {'Header-Field':'value'}
//    maxResponseLength: void 0, // maximum allowd length for the file, the remainder is cut off. Defaults to Infinity
//    method: void 0, // defaults to GET
//    payload: void 0, // request body
//    disableGzip: void 0, // set to false, to disable content gzipping, needed for Node v0.5.9 which has buggy zlib
//    cookies: void 0, // an array of cookie definitions in the form of ['name=val']
//    cookieJar: void 0, // for sharing cookies between requests, see below
//    outputEncoding: void 0, // valid for fetchUrl
//    disableDecoding: void 0, // valid for fetchUrl, set to true to disable automatic charset decoding to utf-8
//    overrideCharset: void 0, // valid for fetchUrl, set input encoding
//    asyncDnsLoookup: void 0, // use high performance asyncronous DNS resolution based on c-ares instead of a thread pool calling getaddrinfo(3)
//    timeout: void 0, // set a timeout in ms
//    agentHttps: void 0, // pass-through http.request agent parameter for https
//    agentHttp: void 0, // pass-through http.request agent parameter for http
//    agent: void 0, // pass-through http.request agent parameter as fallback, if agentHttps or agentHttp are not specified
//    rejectUnauthorized: void 0 // whether to reject self-signed certificates (true, default behavior), or ignore and allow them (false)
//};